import { _decorator, Component, SpriteFrame, Animation } from "cc"
import { FSM_PARAMS_TYPE_ENUM, PARAMS_NAME_ENUM } from "../Enum"
import State from "./State";
import { SubStateMachine } from "./SubStateMachine";
const { ccclass, property } = _decorator;


export interface IParamsValue {
  type: FSM_PARAMS_TYPE_ENUM
  value: boolean | number
}

export const getInitParamsTrigger = ():IParamsValue => {
  return {
    type: FSM_PARAMS_TYPE_ENUM.TRIGGER,
    value: false
  }
}
export const getInitParamsNumber = ():IParamsValue => {
  return {
    type: FSM_PARAMS_TYPE_ENUM.NUMBER,
    value: 0
  }
}

@ccclass('StateMachine')
export abstract class StateMachine extends Component {

  private _currenState: State|SubStateMachine = null;
  params: Record<string, IParamsValue> = {}
  stateMachine: Record<string, State|SubStateMachine> = {}
  animationComponent: Animation
  waitingList: Array<Promise<SpriteFrame[]>> = []

  get currentState() {
    return this._currenState
  }

  set currentState(state: State|SubStateMachine) {
    this._currenState = state
    this._currenState.run()
  }

  isInState(state_name: string){
    return this.currentState === this.stateMachine[state_name]
  }


  getParam(name: string) {

    if (name in this.params) {
      return this.params[name].value
    }

  }

  setParam(name: string, value: boolean | number) {
    if (name in this.params) {
      this.params[name].value = value
      this.run()
      this.resetTrigger()
    }
  }

  resetTrigger() {
    for (const key of Object.keys(this.params)) {
      if (this.params[key].type == FSM_PARAMS_TYPE_ENUM.TRIGGER) {
        this.params[key].value = false
      }
    }
  }

  abstract init(): void

  abstract run(): void


}
